<html><!-- Created using the cpp_pretty_printer from the dlib C++ library.  See http://dlib.net for updates. --><head><title>dlib C++ Library - loss.h</title></head><body bgcolor='white'><pre>
<font color='#009900'>// Copyright (C) 2015  Davis E. King (davis@dlib.net)
</font><font color='#009900'>// License: Boost Software License   See LICENSE.txt for the full license.
</font><font color='#0000FF'>#ifndef</font> DLIB_DNn_LOSS_H_
<font color='#0000FF'>#define</font> DLIB_DNn_LOSS_H_

<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='loss_abstract.h.html'>loss_abstract.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='core.h.html'>core.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='../matrix.h.html'>../matrix.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='tensor_tools.h.html'>tensor_tools.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='../geometry.h.html'>../geometry.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='../image_processing/box_overlap_testing.h.html'>../image_processing/box_overlap_testing.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='../image_processing/full_object_detection.h.html'>../image_processing/full_object_detection.h</a>"
<font color='#0000FF'>#include</font> <font color='#5555FF'>&lt;</font>sstream<font color='#5555FF'>&gt;</font>

<font color='#0000FF'>namespace</font> dlib
<b>{</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>class</font> <b><a name='loss_binary_hinge_'></a>loss_binary_hinge_</b> 
    <b>{</b>
    <font color='#0000FF'>public</font>:

        <font color='#0000FF'>typedef</font> <font color='#0000FF'><u>float</u></font> label_type;

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> SUB_TYPE,
            <font color='#0000FF'>typename</font> label_iterator
            <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'><u>void</u></font> <b><a name='to_label'></a>to_label</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            <font color='#0000FF'>const</font> SUB_TYPE<font color='#5555FF'>&amp;</font> sub,
            label_iterator iter
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;

            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_output</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

            <font color='#0000FF'>const</font> <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> out_data <font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>host</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#5555FF'>*</font>iter<font color='#5555FF'>+</font><font color='#5555FF'>+</font> <font color='#5555FF'>=</font> out_data[i];
            <b>}</b>
        <b>}</b>

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> const_label_iterator,
            <font color='#0000FF'>typename</font> SUBNET
            <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'><u>double</u></font> <b><a name='compute_loss_value_and_gradient'></a>compute_loss_value_and_gradient</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            const_label_iterator truth, 
            SUBNET<font color='#5555FF'>&amp;</font> sub
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_output</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            tensor<font color='#5555FF'>&amp;</font> grad <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_gradient_input</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;

            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>%</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> grad.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;

            <font color='#009900'>// The loss we output is the average loss over the mini-batch.
</font>            <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> scale <font color='#5555FF'>=</font> <font color='#979000'>1.0</font><font color='#5555FF'>/</font>output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'><u>double</u></font> loss <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> out_data <font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>host</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> g <font color='#5555FF'>=</font> grad.<font color='#BB00BB'>host_write_only</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>const</font> <font color='#0000FF'><u>float</u></font> y <font color='#5555FF'>=</font> <font color='#5555FF'>*</font>truth<font color='#5555FF'>+</font><font color='#5555FF'>+</font>;
                <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>y <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>+</font><font color='#979000'>1</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> y <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font>, "<font color='#CC0000'>y: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> y<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> <font color='#0000FF'><u>float</u></font> temp <font color='#5555FF'>=</font> <font color='#979000'>1</font><font color='#5555FF'>-</font>y<font color='#5555FF'>*</font>out_data[i];
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>temp <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                <b>{</b>
                    loss <font color='#5555FF'>+</font><font color='#5555FF'>=</font> scale<font color='#5555FF'>*</font>temp;
                    g[i] <font color='#5555FF'>=</font> <font color='#5555FF'>-</font>scale<font color='#5555FF'>*</font>y;
                <b>}</b>
                <font color='#0000FF'>else</font>
                <b>{</b>
                    g[i] <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
                <b>}</b>
            <b>}</b>
            <font color='#0000FF'>return</font> loss;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='serialize'></a>serialize</b><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> loss_binary_hinge_<font color='#5555FF'>&amp;</font> , std::ostream<font color='#5555FF'>&amp;</font> out<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>loss_binary_hinge_</font>", out<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='deserialize'></a>deserialize</b><font face='Lucida Console'>(</font>loss_binary_hinge_<font color='#5555FF'>&amp;</font> , std::istream<font color='#5555FF'>&amp;</font> in<font face='Lucida Console'>)</font>
        <b>{</b>
            std::string version;
            <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>version, in<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>version <font color='#5555FF'>!</font><font color='#5555FF'>=</font> "<font color='#CC0000'>loss_binary_hinge_</font>"<font face='Lucida Console'>)</font>
                <font color='#0000FF'>throw</font> <font color='#BB00BB'>serialization_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>Unexpected version found while deserializing dlib::loss_binary_hinge_.</font>"<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>friend</font> std::ostream<font color='#5555FF'>&amp;</font> <b><a name='operator'></a>operator</b><font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font><font face='Lucida Console'>(</font>std::ostream<font color='#5555FF'>&amp;</font> out, <font color='#0000FF'>const</font> loss_binary_hinge_<font color='#5555FF'>&amp;</font> <font face='Lucida Console'>)</font>
        <b>{</b>
            out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>loss_binary_hinge</font>";
            <font color='#0000FF'>return</font> out;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='to_xml'></a>to_xml</b><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> loss_binary_hinge_<font color='#5555FF'>&amp;</font> <font color='#009900'>/*item*/</font>, std::ostream<font color='#5555FF'>&amp;</font> out<font face='Lucida Console'>)</font>
        <b>{</b>
            out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>&lt;loss_binary_hinge/&gt;</font>";
        <b>}</b>

    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> SUBNET<font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>using</font> loss_binary_hinge <font color='#5555FF'>=</font> add_loss_layer<font color='#5555FF'>&lt;</font>loss_binary_hinge_, SUBNET<font color='#5555FF'>&gt;</font>;

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>class</font> <b><a name='loss_binary_log_'></a>loss_binary_log_</b> 
    <b>{</b>
    <font color='#0000FF'>public</font>:

        <font color='#0000FF'>typedef</font> <font color='#0000FF'><u>float</u></font> label_type;

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> SUB_TYPE,
            <font color='#0000FF'>typename</font> label_iterator
            <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'><u>void</u></font> <b><a name='to_label'></a>to_label</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            <font color='#0000FF'>const</font> SUB_TYPE<font color='#5555FF'>&amp;</font> sub,
            label_iterator iter
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;

            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_output</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

            <font color='#0000FF'>const</font> <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> out_data <font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>host</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#5555FF'>*</font>iter<font color='#5555FF'>+</font><font color='#5555FF'>+</font> <font color='#5555FF'>=</font> out_data[i];
            <b>}</b>
        <b>}</b>


        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> const_label_iterator,
            <font color='#0000FF'>typename</font> SUBNET
            <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'><u>double</u></font> <b><a name='compute_loss_value_and_gradient'></a>compute_loss_value_and_gradient</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            const_label_iterator truth, 
            SUBNET<font color='#5555FF'>&amp;</font> sub
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_output</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            tensor<font color='#5555FF'>&amp;</font> grad <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_gradient_input</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;

            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>%</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> grad.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>grad.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         grad.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         grad.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;

            tt::<font color='#BB00BB'>sigmoid</font><font face='Lucida Console'>(</font>grad, output_tensor<font face='Lucida Console'>)</font>;

            <font color='#009900'>// The loss we output is the average loss over the mini-batch.
</font>            <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> scale <font color='#5555FF'>=</font> <font color='#979000'>1.0</font><font color='#5555FF'>/</font>output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'><u>double</u></font> loss <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
            <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> g <font color='#5555FF'>=</font> grad.<font color='#BB00BB'>host</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> out_data <font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>host</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>const</font> <font color='#0000FF'><u>float</u></font> y <font color='#5555FF'>=</font> <font color='#5555FF'>*</font>truth<font color='#5555FF'>+</font><font color='#5555FF'>+</font>;
                <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>y <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>+</font><font color='#979000'>1</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> y <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font>, "<font color='#CC0000'>y: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> y<font face='Lucida Console'>)</font>;
                <font color='#0000FF'><u>float</u></font> temp;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>y <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                <b>{</b>
                    temp <font color='#5555FF'>=</font> <font color='#BB00BB'>log1pexp</font><font face='Lucida Console'>(</font><font color='#5555FF'>-</font>out_data[i]<font face='Lucida Console'>)</font>;
                    loss <font color='#5555FF'>+</font><font color='#5555FF'>=</font> scale<font color='#5555FF'>*</font>temp;
                    g[i] <font color='#5555FF'>=</font> scale<font color='#5555FF'>*</font><font face='Lucida Console'>(</font>g[i]<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>;
                <b>}</b>
                <font color='#0000FF'>else</font>
                <b>{</b>
                    temp <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font face='Lucida Console'>(</font><font color='#5555FF'>-</font>out_data[i]<font color='#5555FF'>-</font><font color='#BB00BB'>log1pexp</font><font face='Lucida Console'>(</font><font color='#5555FF'>-</font>out_data[i]<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                    loss <font color='#5555FF'>+</font><font color='#5555FF'>=</font> scale<font color='#5555FF'>*</font>temp;
                    g[i] <font color='#5555FF'>=</font> scale<font color='#5555FF'>*</font>g[i];
                <b>}</b>
            <b>}</b>
            <font color='#0000FF'>return</font> loss;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='serialize'></a>serialize</b><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> loss_binary_log_<font color='#5555FF'>&amp;</font> , std::ostream<font color='#5555FF'>&amp;</font> out<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>loss_binary_log_</font>", out<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='deserialize'></a>deserialize</b><font face='Lucida Console'>(</font>loss_binary_log_<font color='#5555FF'>&amp;</font> , std::istream<font color='#5555FF'>&amp;</font> in<font face='Lucida Console'>)</font>
        <b>{</b>
            std::string version;
            <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>version, in<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>version <font color='#5555FF'>!</font><font color='#5555FF'>=</font> "<font color='#CC0000'>loss_binary_log_</font>"<font face='Lucida Console'>)</font>
                <font color='#0000FF'>throw</font> <font color='#BB00BB'>serialization_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>Unexpected version found while deserializing dlib::loss_binary_log_.</font>"<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>friend</font> std::ostream<font color='#5555FF'>&amp;</font> <b><a name='operator'></a>operator</b><font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font><font face='Lucida Console'>(</font>std::ostream<font color='#5555FF'>&amp;</font> out, <font color='#0000FF'>const</font> loss_binary_log_<font color='#5555FF'>&amp;</font> <font face='Lucida Console'>)</font>
        <b>{</b>
            out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>loss_binary_log</font>";
            <font color='#0000FF'>return</font> out;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='to_xml'></a>to_xml</b><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> loss_binary_log_<font color='#5555FF'>&amp;</font> <font color='#009900'>/*item*/</font>, std::ostream<font color='#5555FF'>&amp;</font> out<font face='Lucida Console'>)</font>
        <b>{</b>
            out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>&lt;loss_binary_log/&gt;</font>";
        <b>}</b>

    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> SUBNET<font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>using</font> loss_binary_log <font color='#5555FF'>=</font> add_loss_layer<font color='#5555FF'>&lt;</font>loss_binary_log_, SUBNET<font color='#5555FF'>&gt;</font>;

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>class</font> <b><a name='loss_multiclass_log_'></a>loss_multiclass_log_</b> 
    <b>{</b>
    <font color='#0000FF'>public</font>:

        <font color='#0000FF'>typedef</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> label_type;

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> SUB_TYPE,
            <font color='#0000FF'>typename</font> label_iterator
            <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'><u>void</u></font> <b><a name='to_label'></a>to_label</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            <font color='#0000FF'>const</font> SUB_TYPE<font color='#5555FF'>&amp;</font> sub,
            label_iterator iter
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_output</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;


            <font color='#009900'>// Note that output_tensor.k() should match the number of labels.
</font>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#009900'>// The index of the largest output for this sample is the label.
</font>                <font color='#5555FF'>*</font>iter<font color='#5555FF'>+</font><font color='#5555FF'>+</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>index_of_max</font><font face='Lucida Console'>(</font><font color='#BB00BB'>rowm</font><font face='Lucida Console'>(</font><font color='#BB00BB'>mat</font><font face='Lucida Console'>(</font>output_tensor<font face='Lucida Console'>)</font>,i<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>


        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> const_label_iterator,
            <font color='#0000FF'>typename</font> SUBNET
            <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'><u>double</u></font> <b><a name='compute_loss_value_and_gradient'></a>compute_loss_value_and_gradient</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            const_label_iterator truth, 
            SUBNET<font color='#5555FF'>&amp;</font> sub
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_output</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            tensor<font color='#5555FF'>&amp;</font> grad <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_gradient_input</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;

            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>%</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> grad.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>grad.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> 
                         grad.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;

            tt::<font color='#BB00BB'>softmax</font><font face='Lucida Console'>(</font>grad, output_tensor<font face='Lucida Console'>)</font>;

            <font color='#009900'>// The loss we output is the average loss over the mini-batch.
</font>            <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> scale <font color='#5555FF'>=</font> <font color='#979000'>1.0</font><font color='#5555FF'>/</font>output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'><u>double</u></font> loss <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
            <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> g <font color='#5555FF'>=</font> grad.<font color='#BB00BB'>host</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> y <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>truth<font color='#5555FF'>+</font><font color='#5555FF'>+</font>;
                <font color='#009900'>// The network must produce a number of outputs that is equal to the number
</font>                <font color='#009900'>// of labels when using this type of loss.
</font>                <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>y <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, "<font color='#CC0000'>y: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> y <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>, output_tensor.k(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> k <font color='#5555FF'>=</font> <font color='#979000'>0</font>; k <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>k<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>const</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> idx <font color='#5555FF'>=</font> i<font color='#5555FF'>*</font>output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>+</font>k;
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>k <font color='#5555FF'>=</font><font color='#5555FF'>=</font> y<font face='Lucida Console'>)</font>
                    <b>{</b>
                        loss <font color='#5555FF'>+</font><font color='#5555FF'>=</font> scale<font color='#5555FF'>*</font><font color='#5555FF'>-</font>std::<font color='#BB00BB'>log</font><font face='Lucida Console'>(</font>g[idx]<font face='Lucida Console'>)</font>;
                        g[idx] <font color='#5555FF'>=</font> scale<font color='#5555FF'>*</font><font face='Lucida Console'>(</font>g[idx]<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>;
                    <b>}</b>
                    <font color='#0000FF'>else</font>
                    <b>{</b>
                        g[idx] <font color='#5555FF'>=</font> scale<font color='#5555FF'>*</font>g[idx];
                    <b>}</b>
                <b>}</b>
            <b>}</b>
            <font color='#0000FF'>return</font> loss;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='serialize'></a>serialize</b><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> loss_multiclass_log_<font color='#5555FF'>&amp;</font> , std::ostream<font color='#5555FF'>&amp;</font> out<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>loss_multiclass_log_</font>", out<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='deserialize'></a>deserialize</b><font face='Lucida Console'>(</font>loss_multiclass_log_<font color='#5555FF'>&amp;</font> , std::istream<font color='#5555FF'>&amp;</font> in<font face='Lucida Console'>)</font>
        <b>{</b>
            std::string version;
            <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>version, in<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>version <font color='#5555FF'>!</font><font color='#5555FF'>=</font> "<font color='#CC0000'>loss_multiclass_log_</font>"<font face='Lucida Console'>)</font>
                <font color='#0000FF'>throw</font> <font color='#BB00BB'>serialization_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>Unexpected version found while deserializing dlib::loss_multiclass_log_.</font>"<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>friend</font> std::ostream<font color='#5555FF'>&amp;</font> <b><a name='operator'></a>operator</b><font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font><font face='Lucida Console'>(</font>std::ostream<font color='#5555FF'>&amp;</font> out, <font color='#0000FF'>const</font> loss_multiclass_log_<font color='#5555FF'>&amp;</font> <font face='Lucida Console'>)</font>
        <b>{</b>
            out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>loss_multiclass_log</font>";
            <font color='#0000FF'>return</font> out;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='to_xml'></a>to_xml</b><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> loss_multiclass_log_<font color='#5555FF'>&amp;</font> <font color='#009900'>/*item*/</font>, std::ostream<font color='#5555FF'>&amp;</font> out<font face='Lucida Console'>)</font>
        <b>{</b>
            out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>&lt;loss_multiclass_log/&gt;</font>";
        <b>}</b>

    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> SUBNET<font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>using</font> loss_multiclass_log <font color='#5555FF'>=</font> add_loss_layer<font color='#5555FF'>&lt;</font>loss_multiclass_log_, SUBNET<font color='#5555FF'>&gt;</font>;

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>struct</font> <b><a name='mmod_options'></a>mmod_options</b>
    <b>{</b>
    <font color='#0000FF'>public</font>:

        <b><a name='mmod_options'></a>mmod_options</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#0000FF'>default</font>;

        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> detector_width <font color='#5555FF'>=</font> <font color='#979000'>80</font>;
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> detector_height <font color='#5555FF'>=</font> <font color='#979000'>80</font>;
        <font color='#0000FF'><u>double</u></font> loss_per_false_alarm <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
        <font color='#0000FF'><u>double</u></font> loss_per_missed_target <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
        <font color='#0000FF'><u>double</u></font> truth_match_iou_threshold <font color='#5555FF'>=</font> <font color='#979000'>0.5</font>;
        test_box_overlap overlaps_nms <font color='#5555FF'>=</font> <b><a name='test_box_overlap'></a>test_box_overlap</b><font face='Lucida Console'>(</font><font color='#979000'>0.4</font><font face='Lucida Console'>)</font>;
        test_box_overlap overlaps_ignore;

        <b><a name='mmod_options'></a>mmod_options</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font>std::vector<font color='#5555FF'>&lt;</font>mmod_rect<font color='#5555FF'>&gt;</font><font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> boxes,
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> target_size <font color='#5555FF'>=</font> <font color='#979000'>6400</font>
        <font face='Lucida Console'>)</font>
        <b>{</b>
            std::vector<font color='#5555FF'>&lt;</font>std::vector<font color='#5555FF'>&lt;</font>rectangle<font color='#5555FF'>&gt;</font><font color='#5555FF'>&gt;</font> temp;

            <font color='#009900'>// find the average width and height.  Then we will set the detector width and
</font>            <font color='#009900'>// height to match the average aspect ratio of the boxes given the target_size.
</font>            running_stats<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font><font color='#5555FF'>&gt;</font> avg_width, avg_height;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'>auto</font><font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> bi : boxes<font face='Lucida Console'>)</font>
            <b>{</b>
                std::vector<font color='#5555FF'>&lt;</font>rectangle<font color='#5555FF'>&gt;</font> rtemp;
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'>auto</font><font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> b : bi<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>b.ignore<font face='Lucida Console'>)</font>
                        <font color='#0000FF'>continue</font>;
                    avg_width.<font color='#BB00BB'>add</font><font face='Lucida Console'>(</font>b.rect.<font color='#BB00BB'>width</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                    avg_height.<font color='#BB00BB'>add</font><font face='Lucida Console'>(</font>b.rect.<font color='#BB00BB'>height</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                    rtemp.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font>b.rect<font face='Lucida Console'>)</font>;
                <b>}</b>
                temp.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font>std::<font color='#BB00BB'>move</font><font face='Lucida Console'>(</font>rtemp<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <b>}</b>

            <font color='#009900'>// now adjust the box size so that it is about target_pixels pixels in size
</font>            <font color='#0000FF'><u>double</u></font> size <font color='#5555FF'>=</font> avg_width.<font color='#BB00BB'>mean</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>avg_height.<font color='#BB00BB'>mean</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'><u>double</u></font> scale <font color='#5555FF'>=</font> std::<font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>target_size<font color='#5555FF'>/</font>size<font face='Lucida Console'>)</font>;

            detector_width <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font><font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>avg_width.<font color='#BB00BB'>mean</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>scale<font color='#5555FF'>+</font><font color='#979000'>0.5</font><font face='Lucida Console'>)</font>;
            detector_height <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font><font face='Lucida Console'>)</font><font face='Lucida Console'>(</font>avg_height.<font color='#BB00BB'>mean</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>scale<font color='#5555FF'>+</font><font color='#979000'>0.5</font><font face='Lucida Console'>)</font>;
            <font color='#009900'>// make sure the width and height never round to zero.
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>detector_width <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                detector_width <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>detector_height <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                detector_height <font color='#5555FF'>=</font> <font color='#979000'>1</font>;


            overlaps_nms <font color='#5555FF'>=</font> <font color='#BB00BB'>find_tight_overlap_tester</font><font face='Lucida Console'>(</font>temp<font face='Lucida Console'>)</font>;
        <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>inline</font> <font color='#0000FF'><u>void</u></font> <b><a name='serialize'></a>serialize</b><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> mmod_options<font color='#5555FF'>&amp;</font> item, std::ostream<font color='#5555FF'>&amp;</font> out<font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'><u>int</u></font> version <font color='#5555FF'>=</font> <font color='#979000'>1</font>;

        <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>version, out<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>item.detector_width, out<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>item.detector_height, out<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>item.loss_per_false_alarm, out<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>item.loss_per_missed_target, out<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>item.truth_match_iou_threshold, out<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>item.overlaps_nms, out<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>item.overlaps_ignore, out<font face='Lucida Console'>)</font>;
    <b>}</b>

    <font color='#0000FF'>inline</font> <font color='#0000FF'><u>void</u></font> <b><a name='deserialize'></a>deserialize</b><font face='Lucida Console'>(</font>mmod_options<font color='#5555FF'>&amp;</font> item, std::istream<font color='#5555FF'>&amp;</font> in<font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'><u>int</u></font> version <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
        <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>version, in<font face='Lucida Console'>)</font>;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>version <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>
            <font color='#0000FF'>throw</font> <font color='#BB00BB'>serialization_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>Unexpected version found while deserializing dlib::mmod_options</font>"<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>item.detector_width, in<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>item.detector_height, in<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>item.loss_per_false_alarm, in<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>item.loss_per_missed_target, in<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>item.truth_match_iou_threshold, in<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>item.overlaps_nms, in<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>item.overlaps_ignore, in<font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>class</font> <b><a name='loss_mmod_'></a>loss_mmod_</b> 
    <b>{</b>
        <font color='#0000FF'>struct</font> <b><a name='intermediate_detection'></a>intermediate_detection</b>
        <b>{</b>
            <b><a name='intermediate_detection'></a>intermediate_detection</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> : detection_confidence<font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>, tensor_offset<font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font> <b>{</b><b>}</b>

            <b><a name='intermediate_detection'></a>intermediate_detection</b><font face='Lucida Console'>(</font>
                rectangle rect_
            <font face='Lucida Console'>)</font> : rect<font face='Lucida Console'>(</font>rect_<font face='Lucida Console'>)</font>, detection_confidence<font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>, tensor_offset<font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font> <b>{</b><b>}</b>

            <b><a name='intermediate_detection'></a>intermediate_detection</b><font face='Lucida Console'>(</font>
                rectangle rect_,
                <font color='#0000FF'><u>double</u></font> detection_confidence_,
                <font color='#0000FF'><u>size_t</u></font> tensor_offset_
            <font face='Lucida Console'>)</font> : rect<font face='Lucida Console'>(</font>rect_<font face='Lucida Console'>)</font>, detection_confidence<font face='Lucida Console'>(</font>detection_confidence_<font face='Lucida Console'>)</font>, tensor_offset<font face='Lucida Console'>(</font>tensor_offset_<font face='Lucida Console'>)</font> <b>{</b><b>}</b>

            rectangle rect;
            <font color='#0000FF'><u>double</u></font> detection_confidence;
            <font color='#0000FF'><u>size_t</u></font> tensor_offset;

            <font color='#0000FF'><u>bool</u></font> <b><a name='operator'></a>operator</b><font color='#5555FF'>&lt;</font><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> intermediate_detection<font color='#5555FF'>&amp;</font> item<font face='Lucida Console'>)</font> <font color='#0000FF'>const</font> <b>{</b> <font color='#0000FF'>return</font> detection_confidence <font color='#5555FF'>&lt;</font> item.detection_confidence; <b>}</b>
        <b>}</b>;

    <font color='#0000FF'>public</font>:

        <font color='#0000FF'>typedef</font> std::vector<font color='#5555FF'>&lt;</font>mmod_rect<font color='#5555FF'>&gt;</font> label_type;

        <b><a name='loss_mmod_'></a>loss_mmod_</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <b>{</b><b>}</b>

        <b><a name='loss_mmod_'></a>loss_mmod_</b><font face='Lucida Console'>(</font>mmod_options options_<font face='Lucida Console'>)</font> : options<font face='Lucida Console'>(</font>options_<font face='Lucida Console'>)</font> <b>{</b><b>}</b>

        <font color='#0000FF'>const</font> mmod_options<font color='#5555FF'>&amp;</font> <b><a name='get_options'></a>get_options</b> <font face='Lucida Console'>(</font>
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font> <b>{</b> <font color='#0000FF'>return</font> options; <b>}</b>

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> SUB_TYPE,
            <font color='#0000FF'>typename</font> label_iterator
            <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'><u>void</u></font> <b><a name='to_label'></a>to_label</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            <font color='#0000FF'>const</font> SUB_TYPE<font color='#5555FF'>&amp;</font> sub,
            label_iterator iter,
            <font color='#0000FF'><u>double</u></font> adjust_threshold <font color='#5555FF'>=</font> <font color='#979000'>0</font>
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_output</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font>,  sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

            std::vector<font color='#5555FF'>&lt;</font>intermediate_detection<font color='#5555FF'>&gt;</font> dets_accum;
            label_type final_dets;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#BB00BB'>tensor_to_dets</font><font face='Lucida Console'>(</font>input_tensor, output_tensor, i, dets_accum, adjust_threshold, sub<font face='Lucida Console'>)</font>;

                <font color='#009900'>// Do non-max suppression
</font>                final_dets.<font color='#BB00BB'>clear</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> dets_accum.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>overlaps_any_box_nms</font><font face='Lucida Console'>(</font>final_dets, dets_accum[i].rect<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                        <font color='#0000FF'>continue</font>;

                    final_dets.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font><font color='#BB00BB'>mmod_rect</font><font face='Lucida Console'>(</font>dets_accum[i].rect, dets_accum[i].detection_confidence<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <b>}</b>

                <font color='#5555FF'>*</font>iter<font color='#5555FF'>+</font><font color='#5555FF'>+</font> <font color='#5555FF'>=</font> std::<font color='#BB00BB'>move</font><font face='Lucida Console'>(</font>final_dets<font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
            <font color='#0000FF'>typename</font> const_label_iterator,
            <font color='#0000FF'>typename</font> SUBNET
            <font color='#5555FF'>&gt;</font>
        <font color='#0000FF'><u>double</u></font> <b><a name='compute_loss_value_and_gradient'></a>compute_loss_value_and_gradient</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            const_label_iterator truth, 
            SUBNET<font color='#5555FF'>&amp;</font> sub
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_output</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            tensor<font color='#5555FF'>&amp;</font> grad <font color='#5555FF'>=</font> sub.<font color='#BB00BB'>get_gradient_input</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;

            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>sub.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> grad.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>input_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;



            <font color='#009900'>// we will scale the loss so that it doesn't get really huge
</font>            <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> scale <font color='#5555FF'>=</font> <font color='#979000'>1.0</font><font color='#5555FF'>/</font>output_tensor.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'><u>double</u></font> loss <font color='#5555FF'>=</font> <font color='#979000'>0</font>;

            <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> g <font color='#5555FF'>=</font> grad.<font color='#BB00BB'>host_write_only</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#009900'>// zero initialize grad.
</font>            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'>auto</font><font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> x : grad<font face='Lucida Console'>)</font>
                x <font color='#5555FF'>=</font> <font color='#979000'>0</font>;

            <font color='#0000FF'>const</font> <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> out_data <font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>host</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;

            std::vector<font color='#5555FF'>&lt;</font>intermediate_detection<font color='#5555FF'>&gt;</font> dets;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#BB00BB'>tensor_to_dets</font><font face='Lucida Console'>(</font>input_tensor, output_tensor, i, dets, <font color='#5555FF'>-</font>options.loss_per_false_alarm, sub<font face='Lucida Console'>)</font>;

                <font color='#0000FF'>const</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> max_num_dets <font color='#5555FF'>=</font> <font color='#979000'>50</font> <font color='#5555FF'>+</font> truth<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#979000'>5</font>;

                <font color='#009900'>// The loss will measure the number of incorrect detections.  A detection is
</font>                <font color='#009900'>// incorrect if it doesn't hit a truth rectangle or if it is a duplicate detection
</font>                <font color='#009900'>// on a truth rectangle.
</font>                loss <font color='#5555FF'>+</font><font color='#5555FF'>=</font> truth<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>options.loss_per_missed_target;
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'>auto</font><font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> x : <font color='#5555FF'>*</font>truth<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#5555FF'>!</font>x.ignore<font face='Lucida Console'>)</font>
                    <b>{</b>
                        point p <font color='#5555FF'>=</font> <font color='#BB00BB'>image_rect_to_feat_coord</font><font face='Lucida Console'>(</font>input_tensor, x, sub<font face='Lucida Console'>)</font>;
                        loss <font color='#5555FF'>-</font><font color='#5555FF'>=</font> out_data[p.<font color='#BB00BB'>y</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> p.<font color='#BB00BB'>x</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>];
                        <font color='#009900'>// compute gradient
</font>                        g[p.<font color='#BB00BB'>y</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> p.<font color='#BB00BB'>x</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>] <font color='#5555FF'>=</font> <font color='#5555FF'>-</font>scale;
                    <b>}</b>
                    <font color='#0000FF'>else</font>
                    <b>{</b>
                        <font color='#009900'>// This box was ignored so shouldn't have been counted in the loss.
</font>                        loss <font color='#5555FF'>-</font><font color='#5555FF'>=</font> <font color='#979000'>1</font>;
                    <b>}</b>
                <b>}</b>

                <font color='#009900'>// Measure the loss augmented score for the detections which hit a truth rect.
</font>                std::vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font><font color='#5555FF'>&gt;</font> <font color='#BB00BB'>truth_score_hits</font><font face='Lucida Console'>(</font>truth<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, <font color='#979000'>0</font><font face='Lucida Console'>)</font>;

                <font color='#009900'>// keep track of which truth boxes we have hit so far.
</font>                std::vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>bool</u></font><font color='#5555FF'>&gt;</font> <font color='#BB00BB'>hit_truth_table</font><font face='Lucida Console'>(</font>truth<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font><font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, <font color='#979000'>false</font><font face='Lucida Console'>)</font>;

                std::vector<font color='#5555FF'>&lt;</font>intermediate_detection<font color='#5555FF'>&gt;</font> final_dets;
                <font color='#009900'>// The point of this loop is to fill out the truth_score_hits array. 
</font>                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> dets.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> final_dets.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font> max_num_dets; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>overlaps_any_box_nms</font><font face='Lucida Console'>(</font>final_dets, dets[i].rect<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                        <font color='#0000FF'>continue</font>;

                    <font color='#0000FF'>const</font> std::pair<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>int</u></font><font color='#5555FF'>&gt;</font> hittruth <font color='#5555FF'>=</font> <font color='#BB00BB'>find_best_match</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>truth, dets[i].rect<font face='Lucida Console'>)</font>;

                    final_dets.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font>dets[i].rect<font face='Lucida Console'>)</font>;

                    <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> truth_match <font color='#5555FF'>=</font> hittruth.first;
                    <font color='#009900'>// if hit truth rect
</font>                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>truth_match <font color='#5555FF'>&gt;</font> options.truth_match_iou_threshold<font face='Lucida Console'>)</font>
                    <b>{</b>
                        <font color='#009900'>// if this is the first time we have seen a detect which hit (*truth)[hittruth.second]
</font>                        <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> score <font color='#5555FF'>=</font> dets[i].detection_confidence;
                        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>hit_truth_table[hittruth.second] <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>false</font><font face='Lucida Console'>)</font>
                        <b>{</b>
                            hit_truth_table[hittruth.second] <font color='#5555FF'>=</font> <font color='#979000'>true</font>;
                            truth_score_hits[hittruth.second] <font color='#5555FF'>+</font><font color='#5555FF'>=</font> score;
                        <b>}</b>
                        <font color='#0000FF'>else</font>
                        <b>{</b>
                            truth_score_hits[hittruth.second] <font color='#5555FF'>+</font><font color='#5555FF'>=</font> score <font color='#5555FF'>+</font> options.loss_per_false_alarm;
                        <b>}</b>
                    <b>}</b>
                <b>}</b>


                hit_truth_table.<font color='#BB00BB'>assign</font><font face='Lucida Console'>(</font>hit_truth_table.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, <font color='#979000'>false</font><font face='Lucida Console'>)</font>;
                final_dets.<font color='#BB00BB'>clear</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;


                <font color='#009900'>// Now figure out which detections jointly maximize the loss and detection score sum.  We
</font>                <font color='#009900'>// need to take into account the fact that allowing a true detection in the output, while 
</font>                <font color='#009900'>// initially reducing the loss, may allow us to increase the loss later with many duplicate
</font>                <font color='#009900'>// detections.
</font>                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> dets.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> final_dets.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font> max_num_dets; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>overlaps_any_box_nms</font><font face='Lucida Console'>(</font>final_dets, dets[i].rect<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                        <font color='#0000FF'>continue</font>;

                    <font color='#0000FF'>const</font> std::pair<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>int</u></font><font color='#5555FF'>&gt;</font> hittruth <font color='#5555FF'>=</font> <font color='#BB00BB'>find_best_match</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>truth, dets[i].rect<font face='Lucida Console'>)</font>;

                    <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> truth_match <font color='#5555FF'>=</font> hittruth.first;
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>truth_match <font color='#5555FF'>&gt;</font> options.truth_match_iou_threshold<font face='Lucida Console'>)</font>
                    <b>{</b>
                        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>truth_score_hits[hittruth.second] <font color='#5555FF'>&gt;</font> options.loss_per_missed_target<font face='Lucida Console'>)</font>
                        <b>{</b>
                            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#5555FF'>!</font>hit_truth_table[hittruth.second]<font face='Lucida Console'>)</font>
                            <b>{</b>
                                hit_truth_table[hittruth.second] <font color='#5555FF'>=</font> <font color='#979000'>true</font>;
                                final_dets.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font>dets[i]<font face='Lucida Console'>)</font>;
                                loss <font color='#5555FF'>-</font><font color='#5555FF'>=</font> options.loss_per_missed_target;
                            <b>}</b>
                            <font color='#0000FF'>else</font>
                            <b>{</b>
                                final_dets.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font>dets[i]<font face='Lucida Console'>)</font>;
                                loss <font color='#5555FF'>+</font><font color='#5555FF'>=</font> options.loss_per_false_alarm;
                            <b>}</b>
                        <b>}</b>
                    <b>}</b>
                    <font color='#0000FF'>else</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#5555FF'>!</font><font color='#BB00BB'>overlaps_ignore_box</font><font face='Lucida Console'>(</font><font color='#5555FF'>*</font>truth, dets[i].rect<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                    <b>{</b>
                        <font color='#009900'>// didn't hit anything
</font>                        final_dets.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font>dets[i]<font face='Lucida Console'>)</font>;
                        loss <font color='#5555FF'>+</font><font color='#5555FF'>=</font> options.loss_per_false_alarm;
                    <b>}</b>
                <b>}</b>

                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'>auto</font><font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> x : final_dets<font face='Lucida Console'>)</font>
                <b>{</b>
                    loss <font color='#5555FF'>+</font><font color='#5555FF'>=</font> out_data[x.tensor_offset];
                    g[x.tensor_offset] <font color='#5555FF'>+</font><font color='#5555FF'>=</font> scale;
                <b>}</b>

                <font color='#5555FF'>+</font><font color='#5555FF'>+</font>truth;
                g        <font color='#5555FF'>+</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
                out_data <font color='#5555FF'>+</font><font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <b>}</b> <font color='#009900'>// END for (long i = 0; i &lt; output_tensor.num_samples(); ++i)
</font>

            <font color='#009900'>// Here we scale the loss so that it's roughly equal to the number of mistakes
</font>            <font color='#009900'>// in an image.  Note that this scaling is different than the scaling we
</font>            <font color='#009900'>// applied to the gradient but it doesn't matter since the loss value isn't
</font>            <font color='#009900'>// used to update parameters.  It's used only for display and to check if we
</font>            <font color='#009900'>// have converged.  So it doesn't matter that they are scaled differently and
</font>            <font color='#009900'>// this way the loss that is displayed is readily interpretable to the user.
</font>            <font color='#0000FF'>return</font> loss<font color='#5555FF'>/</font>output_tensor.<font color='#BB00BB'>num_samples</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        <b>}</b>


        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='serialize'></a>serialize</b><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> loss_mmod_<font color='#5555FF'>&amp;</font> item, std::ostream<font color='#5555FF'>&amp;</font> out<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>loss_mmod_</font>", out<font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>serialize</font><font face='Lucida Console'>(</font>item.options, out<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='deserialize'></a>deserialize</b><font face='Lucida Console'>(</font>loss_mmod_<font color='#5555FF'>&amp;</font> item, std::istream<font color='#5555FF'>&amp;</font> in<font face='Lucida Console'>)</font>
        <b>{</b>
            std::string version;
            <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>version, in<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>version <font color='#5555FF'>!</font><font color='#5555FF'>=</font> "<font color='#CC0000'>loss_mmod_</font>"<font face='Lucida Console'>)</font>
                <font color='#0000FF'>throw</font> <font color='#BB00BB'>serialization_error</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>Unexpected version found while deserializing dlib::loss_mmod_.</font>"<font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>deserialize</font><font face='Lucida Console'>(</font>item.options, in<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>friend</font> std::ostream<font color='#5555FF'>&amp;</font> <b><a name='operator'></a>operator</b><font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font><font face='Lucida Console'>(</font>std::ostream<font color='#5555FF'>&amp;</font> out, <font color='#0000FF'>const</font> loss_mmod_<font color='#5555FF'>&amp;</font> <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// TODO, add options fields
</font>            out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>loss_mmod</font>";
            <font color='#0000FF'>return</font> out;
        <b>}</b>

        <font color='#0000FF'>friend</font> <font color='#0000FF'><u>void</u></font> <b><a name='to_xml'></a>to_xml</b><font face='Lucida Console'>(</font><font color='#0000FF'>const</font> loss_mmod_<font color='#5555FF'>&amp;</font> <font color='#009900'>/*item*/</font>, std::ostream<font color='#5555FF'>&amp;</font> out<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// TODO, add options fields
</font>            out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>&lt;loss_mmod/&gt;</font>";
        <b>}</b>

    <font color='#0000FF'>private</font>:

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> net_type<font color='#5555FF'>&gt;</font>
        <font color='#0000FF'><u>void</u></font> <b><a name='tensor_to_dets'></a>tensor_to_dets</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor,
            <font color='#0000FF'><u>long</u></font> i,
            std::vector<font color='#5555FF'>&lt;</font>intermediate_detection<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> dets_accum,
            <font color='#0000FF'><u>double</u></font> adjust_threshold,
            <font color='#0000FF'>const</font> net_type<font color='#5555FF'>&amp;</font> net 
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>net.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font>,net.<font color='#BB00BB'>sample_expansion_factor</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_CASSERT</font><font face='Lucida Console'>(</font>output_tensor.<font color='#BB00BB'>k</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>float</u></font><font color='#5555FF'>*</font> out_data <font color='#5555FF'>=</font> output_tensor.<font color='#BB00BB'>host</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>i;
            <font color='#009900'>// scan the final layer and output the positive scoring locations
</font>            dets_accum.<font color='#BB00BB'>clear</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> <font color='#979000'>0</font>; r <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> c <font color='#5555FF'>=</font> <font color='#979000'>0</font>; c <font color='#5555FF'>&lt;</font> output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>c<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'><u>double</u></font> score <font color='#5555FF'>=</font> out_data[r<font color='#5555FF'>*</font>output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> c];
                    <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>score <font color='#5555FF'>&gt;</font> adjust_threshold<font face='Lucida Console'>)</font>
                    <b>{</b>
                        dpoint p <font color='#5555FF'>=</font> <font color='#BB00BB'>output_tensor_to_input_tensor</font><font face='Lucida Console'>(</font>net, <font color='#BB00BB'>point</font><font face='Lucida Console'>(</font>c,r<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                        drectangle rect <font color='#5555FF'>=</font> <font color='#BB00BB'>centered_drect</font><font face='Lucida Console'>(</font>p, options.detector_width, options.detector_height<font face='Lucida Console'>)</font>;
                        rect <font color='#5555FF'>=</font> <font color='#BB00BB'>input_layer</font><font face='Lucida Console'>(</font>net<font face='Lucida Console'>)</font>.<font color='#BB00BB'>tensor_space_to_image_space</font><font face='Lucida Console'>(</font>input_tensor,rect<font face='Lucida Console'>)</font>;

                        dets_accum.<font color='#BB00BB'>push_back</font><font face='Lucida Console'>(</font><font color='#BB00BB'>intermediate_detection</font><font face='Lucida Console'>(</font>rect, score, r<font color='#5555FF'>*</font>output_tensor.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> c<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                    <b>}</b>
                <b>}</b>
            <b>}</b>
            std::<font color='#BB00BB'>sort</font><font face='Lucida Console'>(</font>dets_accum.<font color='#BB00BB'>rbegin</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, dets_accum.<font color='#BB00BB'>rend</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
        <b>}</b>


        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> net_type<font color='#5555FF'>&gt;</font>
        point <b><a name='image_rect_to_feat_coord'></a>image_rect_to_feat_coord</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> input_tensor,
            <font color='#0000FF'>const</font> rectangle<font color='#5555FF'>&amp;</font> rect,
            <font color='#0000FF'>const</font> net_type<font color='#5555FF'>&amp;</font> net
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font> 
        <b>{</b>
            <font color='#0000FF'>using</font> <font color='#0000FF'>namespace</font> std;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#5555FF'>!</font><font color='#BB00BB'>input_layer</font><font face='Lucida Console'>(</font>net<font face='Lucida Console'>)</font>.<font color='#BB00BB'>image_contained_point</font><font face='Lucida Console'>(</font>input_tensor,<font color='#BB00BB'>center</font><font face='Lucida Console'>(</font>rect<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                std::ostringstream sout;
                sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>Encountered a truth rectangle located at </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> rect <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> that is outside the image.</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>The center of each truth rectangle must be within the image.</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                <font color='#0000FF'>throw</font> <font color='#BB00BB'>impossible_labeling_error</font><font face='Lucida Console'>(</font>sout.<font color='#BB00BB'>str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <b>}</b>

            <font color='#009900'>// Compute the scale we need to be at to get from rect to our detection window.
</font>            <font color='#009900'>// Note that we compute the scale as the max of two numbers.  It doesn't
</font>            <font color='#009900'>// actually matter which one we pick, because if they are very different then
</font>            <font color='#009900'>// it means the box can't be matched by the sliding window.  But picking the
</font>            <font color='#009900'>// max causes the right error message to be selected in the logic below.
</font>            <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> scale <font color='#5555FF'>=</font> std::<font color='#BB00BB'>max</font><font face='Lucida Console'>(</font>options.detector_width<font color='#5555FF'>/</font><font face='Lucida Console'>(</font><font color='#0000FF'><u>double</u></font><font face='Lucida Console'>)</font>rect.<font color='#BB00BB'>width</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, options.detector_height<font color='#5555FF'>/</font><font face='Lucida Console'>(</font><font color='#0000FF'><u>double</u></font><font face='Lucida Console'>)</font>rect.<font color='#BB00BB'>height</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>const</font> rectangle mapped_rect <font color='#5555FF'>=</font> <font color='#BB00BB'>input_layer</font><font face='Lucida Console'>(</font>net<font face='Lucida Console'>)</font>.<font color='#BB00BB'>image_space_to_tensor_space</font><font face='Lucida Console'>(</font>input_tensor, std::<font color='#BB00BB'>min</font><font face='Lucida Console'>(</font><font color='#979000'>1.0</font>,scale<font face='Lucida Console'>)</font>, rect<font face='Lucida Console'>)</font>;

            <font color='#009900'>// compute the detection window that we would use at this position.
</font>            point tensor_p <font color='#5555FF'>=</font> <font color='#BB00BB'>center</font><font face='Lucida Console'>(</font>mapped_rect<font face='Lucida Console'>)</font>;
            rectangle det_window <font color='#5555FF'>=</font> <font color='#BB00BB'>centered_rect</font><font face='Lucida Console'>(</font>tensor_p, options.detector_width,options.detector_height<font face='Lucida Console'>)</font>;
            det_window <font color='#5555FF'>=</font> <font color='#BB00BB'>input_layer</font><font face='Lucida Console'>(</font>net<font face='Lucida Console'>)</font>.<font color='#BB00BB'>tensor_space_to_image_space</font><font face='Lucida Console'>(</font>input_tensor, det_window<font face='Lucida Console'>)</font>;

            <font color='#009900'>// make sure the rect can actually be represented by the image pyramid we are
</font>            <font color='#009900'>// using.
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>box_intersection_over_union</font><font face='Lucida Console'>(</font>rect, det_window<font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font> options.truth_match_iou_threshold<font face='Lucida Console'>)</font>
            <b>{</b>
                std::ostringstream sout;
                sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>Encountered a truth rectangle with a width and height of </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> rect.<font color='#BB00BB'>width</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> and </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> rect.<font color='#BB00BB'>height</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>.</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>The image pyramid and sliding window can't output a rectangle of this shape. </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> detector_area <font color='#5555FF'>=</font> options.detector_width<font color='#5555FF'>*</font>options.detector_height;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>mapped_rect.<font color='#BB00BB'>area</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>/</font>detector_area <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font> options.truth_match_iou_threshold<font face='Lucida Console'>)</font>
                <b>{</b>
                    sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>This is because the rectangle is smaller than the detection window which has a width</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                    sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>and height of </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> options.detector_width <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> and </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> options.detector_height <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>.</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                <b>}</b>
                <font color='#0000FF'>else</font>
                <b>{</b>
                    sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>This is because the rectangle's aspect ratio is too different from the detection window,</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                    sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>which has a width and height of </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> options.detector_width <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> and </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> options.detector_height <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>.</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                <b>}</b>
                <font color='#0000FF'>throw</font> <font color='#BB00BB'>impossible_labeling_error</font><font face='Lucida Console'>(</font>sout.<font color='#BB00BB'>str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <b>}</b>

            <font color='#009900'>// now map through the CNN to the output layer.
</font>            tensor_p <font color='#5555FF'>=</font> <font color='#BB00BB'>input_tensor_to_output_tensor</font><font face='Lucida Console'>(</font>net,tensor_p<font face='Lucida Console'>)</font>;

            <font color='#0000FF'>const</font> tensor<font color='#5555FF'>&amp;</font> output_tensor <font color='#5555FF'>=</font> net.<font color='#BB00BB'>get_output</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#5555FF'>!</font><font color='#BB00BB'>get_rect</font><font face='Lucida Console'>(</font>output_tensor<font face='Lucida Console'>)</font>.<font color='#BB00BB'>contains</font><font face='Lucida Console'>(</font>tensor_p<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                std::ostringstream sout;
                sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>Encountered a truth rectangle located at </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> rect <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'> that is too close to the edge</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                sout <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>of the image to be captured by the CNN features.</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> endl;
                <font color='#0000FF'>throw</font> <font color='#BB00BB'>impossible_labeling_error</font><font face='Lucida Console'>(</font>sout.<font color='#BB00BB'>str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <b>}</b>

            <font color='#0000FF'>return</font> tensor_p;
        <b>}</b>


        <font color='#0000FF'><u>bool</u></font> <b><a name='overlaps_ignore_box'></a>overlaps_ignore_box</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font>mmod_rect<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> boxes,
            <font color='#0000FF'>const</font> rectangle<font color='#5555FF'>&amp;</font> rect
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'>auto</font><font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> b : boxes<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>b.ignore <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> options.<font color='#BB00BB'>overlaps_ignore</font><font face='Lucida Console'>(</font>b, rect<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                    <font color='#0000FF'>return</font> <font color='#979000'>true</font>;
            <b>}</b>
            <font color='#0000FF'>return</font> <font color='#979000'>false</font>;
        <b>}</b>

        std::pair<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>int</u></font><font color='#5555FF'>&gt;</font> <b><a name='find_best_match'></a>find_best_match</b><font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font>mmod_rect<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> boxes,
            <font color='#0000FF'>const</font> rectangle<font color='#5555FF'>&amp;</font> rect
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#0000FF'><u>double</u></font> match <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
            <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>int</u></font> best_idx <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> boxes.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>boxes[i].ignore<font face='Lucida Console'>)</font>
                    <font color='#0000FF'>continue</font>;

                <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> new_match <font color='#5555FF'>=</font> <font color='#BB00BB'>box_intersection_over_union</font><font face='Lucida Console'>(</font>rect, boxes[i]<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>new_match <font color='#5555FF'>&gt;</font> match<font face='Lucida Console'>)</font>
                <b>{</b>
                    match <font color='#5555FF'>=</font> new_match;
                    best_idx <font color='#5555FF'>=</font> i;
                <b>}</b>
            <b>}</b>

            <font color='#0000FF'>return</font> std::<font color='#BB00BB'>make_pair</font><font face='Lucida Console'>(</font>match,best_idx<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> T<font color='#5555FF'>&gt;</font>
        <font color='#0000FF'>inline</font> <font color='#0000FF'><u>bool</u></font> <b><a name='overlaps_any_box_nms'></a>overlaps_any_box_nms</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> rects,
            <font color='#0000FF'>const</font> rectangle<font color='#5555FF'>&amp;</font> rect
        <font face='Lucida Console'>)</font> <font color='#0000FF'>const</font>
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'>auto</font><font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> r : rects<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>options.<font color='#BB00BB'>overlaps_nms</font><font face='Lucida Console'>(</font>r.rect, rect<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                    <font color='#0000FF'>return</font> <font color='#979000'>true</font>;
            <b>}</b>
            <font color='#0000FF'>return</font> <font color='#979000'>false</font>;
        <b>}</b>


        mmod_options options;

    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> SUBNET<font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>using</font> loss_mmod <font color='#5555FF'>=</font> add_loss_layer<font color='#5555FF'>&lt;</font>loss_mmod_, SUBNET<font color='#5555FF'>&gt;</font>;

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<b>}</b>

<font color='#0000FF'>#endif</font> <font color='#009900'>// DLIB_DNn_LOSS_H_
</font>

</pre></body></html>